package com.kizitonwose.calendarview.fraction;

import com.kizitonwose.calendarview.CalendarView;
import com.kizitonwose.calendarview.QuickBaseItemProvider;
import com.kizitonwose.calendarview.ResourceTable;
import com.kizitonwose.calendarview.model.CalendarDay;
import com.kizitonwose.calendarview.model.CalendarMonth;
import com.kizitonwose.calendarview.model.enums.DayOwner;
import com.kizitonwose.calendarview.ui.ViewContainer;
import com.kizitonwose.calendarview.uinterface.DayBinder;
import com.kizitonwose.calendarview.uinterface.MonthHeaderFooterBinder;
import com.kizitonwose.calendarview.uinterface.MonthScrollListener;
import com.kizitonwose.calendarview.utils.*;
import ohos.aafwk.content.Intent;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.*;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.utils.Color;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.time.format.TextStyle;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;

/**
 * @author LiuQingHua
 * @version 1.0
 * @date 2021/3/8 19:09
 */
public class Example5Fraction extends BaseFraction {
    private CalendarView exFiveCalendar;
    private Text exFiveMonthYearText;
    private Image exFivePreviousMonthImage;
    private Image exFiveNextMonthImage;
    private LocalDate selectedDate;
    private LocalDate today = LocalDate.now();
    private DateTimeFormatter monthTitleFormatter = DateTimeFormatter.ofPattern("MMMM");
    private BaseItemProvider itemProvider;
    private ListContainer exFiveRv;
    private List<Flight> data = new ArrayList<>();
    private Map<LocalDate, List<Flight>> flights = IterableExtension.getInstance(Util.generateFlights()).groupBy(new IterableExtension.Convert<Flight, LocalDate>() {
        @Override
        public LocalDate convert(Flight flight) {
            return flight.time.toLocalDate();
        }
    });

    @Override
    protected int getLayoutResId() {
        return ResourceTable.Layout_example_5_fraction;
    }

    @Override
    protected int getStatusBarColor() {
        return mContext.getColor(ResourceTable.Color_example_5_toolbar_color);
    }

    @Override
    protected void initComponent(Component content, ComponentContainer container, Intent intent) {
        exFiveCalendar = findComponentById(ResourceTable.Id_exFiveCalendar);
        exFiveMonthYearText = findComponentById(ResourceTable.Id_exFiveMonthYearText);
        exFivePreviousMonthImage = findComponentById(ResourceTable.Id_exFivePreviousMonthImage);
        exFiveNextMonthImage = findComponentById(ResourceTable.Id_exFiveNextMonthImage);
        exFiveRv = findComponentById(ResourceTable.Id_exFiveRv);
        exFiveRv.setOrientation(Component.VERTICAL);
        exFiveRv.setItemProvider(itemProvider = new QuickBaseItemProvider<Flight>(mContext,data) {
            private DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE'\n'dd MMM'\n'HH:mm");

            @Override
            protected int getComponentResourceLayout(ComponentContainer componentContainer, int componentType) {
                return ResourceTable.Layout_example_5_event_item_view;
            }

            @Override
            protected void bindComponentHolder(BaseComponentHolder holder, int position, int componentType) {
                Flight flight = getItem(position);
                int w = (int) (DisplayUtils.getWidth(mContext) * 0.143);
                holder.getComponentById(ResourceTable.Id_itemFlightDateText).setWidth(w);
                holder.getComponentById(ResourceTable.Id_itemFlightDepartureImage).setWidth(w);
                holder.getComponentById(ResourceTable.Id_itemFlightDepartureLayout).setWidth(w * 2 - AttrHelper.vp2px(1, AttrHelper.getDensity(mContext)));
                holder.getComponentById(ResourceTable.Id_itemFlightDestinationImage).setWidth(w);
                holder.getComponentById(ResourceTable.Id_itemFlightDestinationLayout).setWidth(w * 2 - AttrHelper.vp2px(1, AttrHelper.getDensity(mContext)));
                ShapeElement element = new ShapeElement();
                element.setRgbColor(RgbColor.fromArgbInt(mContext.getColor(flight.color)));
                holder.setText(ResourceTable.Id_itemFlightDateText, formatter.format(flight.time))
                        .setBackground(ResourceTable.Id_itemFlightDateText, element);
                holder.setText(ResourceTable.Id_itemDepartureAirportCodeText, flight.departure.code);
                holder.setText(ResourceTable.Id_itemDepartureAirportCityText, flight.departure.city);

                holder.setText(ResourceTable.Id_itemDestinationAirportCodeText, flight.destination.code);
                holder.setText(ResourceTable.Id_itemDestinationAirportCityText, flight.destination.city);
            }
        });
        DayOfWeek[] daysOfWeek = DayExtensions.daysOfWeekFromLocale();
        YearMonth currentMonth = YearMonth.now();
        exFiveCalendar.setup(currentMonth.minusMonths(10), currentMonth.plusMonths(10), daysOfWeek[0]);
        exFiveCalendar.scrollToMonth(currentMonth);
        exFiveCalendar.setDayBinder(new DayBinder<DayViewContainer>() {

            @Override
            public DayViewContainer create(Component component) {
                return new DayViewContainer(component);
            }

            @Override
            public void bind(DayViewContainer container, CalendarDay day) {
                try {
                    container.day = day;
                    Text textView = container.textView;
                    Component layout = container.exFiveDayLayout;
                    textView.setText(String.valueOf(day.getDate().getDayOfMonth()));

                    Component flightTopView = container.exFiveDayFlightTop;
                    Component flightBottomView = container.exFiveDayFlightBottom;
                    flightTopView.setBackground(null);
                    flightBottomView.setBackground(null);

                    if (day.getOwner() == DayOwner.THIS_MONTH) {
                        textView.setTextColor(new Color(mContext.getResourceManager().getElement(ResourceTable.Color_example_5_text_grey).getColor()));
                        if (selectedDate != null && day.getDate().isEqual(selectedDate)) {
                            ShapeElement element = new ShapeElement(mContext, ResourceTable.Graphic_example_5_selected_bg);
                            layout.setBackground(element);
                        } else {
                            layout.setBackground(null);
                        }
                        List<Flight> list = flights.get(day.getDate());
                        if (list != null) {
                            if (list.size() == 1) {
                                ShapeElement element = new ShapeElement();
                                element.setRgbColor(RgbColor.fromArgbInt(mContext.getColor(list.get(0).color)));
                                flightBottomView.setBackground(element);
                            } else {
                                ShapeElement element = new ShapeElement();
                                element.setRgbColor(RgbColor.fromArgbInt(mContext.getColor(list.get(0).color)));
                                flightTopView.setBackground(element);
                                ShapeElement element1 = new ShapeElement();
                                element1.setRgbColor(RgbColor.fromArgbInt(mContext.getColor(list.get(1).color)));
                                flightBottomView.setBackground(element1);
                            }
                        }


                    } else {
                        textView.setTextColor(new Color(mContext.getResourceManager().getElement(ResourceTable.Color_example_5_text_grey_light).getColor()));
                        textView.setBackground(null);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        exFiveCalendar.setMonthHeaderBinder(new MonthHeaderFooterBinder<MonthViewContainer>() {
            @Override
            public MonthViewContainer create(Component component) {
                return new MonthViewContainer(component);
            }

            @Override
            public void bind(MonthViewContainer container, CalendarMonth month) {
                // Setup each header day text if we have not done that already.
                if (container.legendLayout.getTag() == null) {
                    container.legendLayout.setTag(month.getYearMonth());
                    int childCount = container.legendLayout.getChildCount();
                    for (int i = 0; i < childCount; i++) {
                        Text text = (Text) container.legendLayout.getComponentAt(i);
                        text.setText(daysOfWeek[i].getDisplayName(TextStyle.SHORT, Locale.ENGLISH).toUpperCase(Locale.ENGLISH));
                        try {
                            text.setTextColor(new Color(mContext.getResourceManager().getElement(ResourceTable.Color_example_5_text_grey).getColor()));
                            text.setTextSize(12, Text.TextSizeType.FP);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        });
        exFiveCalendar.setMonthScrollListener(new MonthScrollListener() {
            @Override
            public void onMonthScroll(CalendarMonth month) {
                String title = String.format("%s %s", monthTitleFormatter.format(month.getYearMonth()), month.getYearMonth().getYear());
                exFiveMonthYearText.setText(title);
                if (selectedDate != null) {
                    LocalDate it = selectedDate;
                    // Clear selection if we scroll to a new month.
                    selectedDate = null;
                    exFiveCalendar.notifyDateChanged(it);
                    updateAdapterForDate(null);
                }
            }
        });

        exFiveNextMonthImage.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                if (exFiveCalendar.findFirstVisibleMonth() != null) {
                    exFiveCalendar.scrollToMonth(exFiveCalendar.findFirstVisibleMonth().getYearMonth().plusMonths(1));
                }
            }
        });
        exFivePreviousMonthImage.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                if (exFiveCalendar.findFirstVisibleMonth() != null) {
                    exFiveCalendar.scrollToMonth(exFiveCalendar.findFirstVisibleMonth().getYearMonth().minusMonths(1));
                }
            }
        });
    }


    class DayViewContainer extends ViewContainer {
        CalendarDay day;
        Text textView;
        Component exFiveDayLayout;
        Component exFiveDayFlightTop;
        Component exFiveDayFlightBottom;

        public DayViewContainer(Component component) {
            super(component);
            exFiveDayLayout = component.findComponentById(ResourceTable.Id_exFiveDayLayout);
            textView = (Text) component.findComponentById(ResourceTable.Id_exFiveDayText);
            exFiveDayFlightTop = component.findComponentById(ResourceTable.Id_exFiveDayFlightTop);
            exFiveDayFlightBottom = component.findComponentById(ResourceTable.Id_exFiveDayFlightBottom);
            component.setClickedListener(new Component.ClickedListener() {
                @Override
                public void onClick(Component component) {
                    if (day.getOwner() == DayOwner.THIS_MONTH) {
                        if (selectedDate == null || !selectedDate.isEqual(day.getDate())) {
                            LocalDate oldDate = selectedDate;
                            selectedDate = day.getDate();
                            exFiveCalendar.notifyDateChanged(day.getDate());
                            if (oldDate != null) {
                                exFiveCalendar.notifyDateChanged(oldDate);
                            }
                        }
                        updateAdapterForDate(day.getDate());
                    }
                }

            });

        }
    }

    private void updateAdapterForDate(LocalDate date) {
        data.clear();
        if (date != null) {
            data.addAll(ListExtension.getInstance(flights.get(date)).orEmpty().getList());
        }
        itemProvider.notifyDataChanged();
    }

    static class MonthViewContainer extends ViewContainer {
        ComponentContainer legendLayout;

        MonthViewContainer(Component component) {
            super(component);
            legendLayout = (ComponentContainer) component.findComponentById(ResourceTable.Id_legendLayout);
        }
    }

    public static class Flight {
        LocalDateTime time;
        Airport departure;
        Airport destination;
        int color;

        public Flight(LocalDateTime time, Airport departure, Airport destination, int color) {
            this.time = time;
            this.departure = departure;
            this.destination = destination;
            this.color = color;
        }


    }

    public static class Airport {
        String city;
        String code;

        public Airport(String city, String code) {
            this.city = city;
            this.code = code;
        }
    }
}
